package com.duoqin.payservice.viewmodel;

import android.app.Application;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.support.annotation.NonNull;
import android.util.Log;
import android.widget.Toast;

import com.duoqin.common.data.DefaultResponse;
import com.duoqin.common.data.remote.ApiClient;
import com.duoqin.payservice.data.AccountResponse;
import com.duoqin.payservice.data.CommoditiesResponse;
import com.duoqin.payservice.data.CommodityResponse;
import com.duoqin.payservice.data.ExpenseRequest;
import com.duoqin.payservice.data.ExpenseResponse;
import com.duoqin.payservice.data.ExpenseSummaryResponse;
import com.duoqin.payservice.data.HistoryResponse;
import com.duoqin.payservice.data.RechargeHistoryResponse;
import com.duoqin.payservice.data.RechargeRequest;
import com.duoqin.payservice.data.RechargeResponse;
import com.duoqin.payservice.data.remote.PayApiInterface;
import com.duoqin.syncassistant.R;
import com.duoqin.syncassistant.viewmodel.BaseViewModel;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class PayViewModel extends BaseViewModel {
    private static final String TAG = "duoqin_PayViewModel";

    private PayApiInterface mPayApiInterface;
    private MutableLiveData<AccountResponse> mAccountResponse;
    private MutableLiveData<CommoditiesResponse> mCommoditiesResponse;
    private MutableLiveData<CommodityResponse> mCommodityResponse;
    private MutableLiveData<DefaultResponse> mOrderResponse;
    private MutableLiveData<HistoryResponse> mHistoryResponse;
    private MutableLiveData<RechargeHistoryResponse> mRechargeHistoryResponse;
    private MutableLiveData<ExpenseSummaryResponse> mExpenseSummaryResponse;
    private MutableLiveData<RechargeResponse> mRechargeResponse;
    private MutableLiveData<ExpenseResponse> mExpenseResponse;

    public PayViewModel(@NonNull Application application) {
        super(application);
        mPayApiInterface = ApiClient.getClient().create(PayApiInterface.class);
    }

    public LiveData<AccountResponse> accountResponseLiveData() {
        if (mAccountResponse == null) {
            mAccountResponse = new MutableLiveData<>();
        }
        return mAccountResponse;
    }

    public LiveData<CommoditiesResponse> commoditiesResponseLiveData() {
        if (mCommoditiesResponse == null) {
            mCommoditiesResponse = new MutableLiveData<>();
        }
        return mCommoditiesResponse;
    }

    public LiveData<CommodityResponse> commodityResponseLiveData() {
        if (mCommodityResponse == null) {
            mCommodityResponse = new MutableLiveData<>();
        }
        return mCommodityResponse;
    }

    public LiveData<DefaultResponse> orderResponseLiveData() {
        if (mOrderResponse == null) {
            mOrderResponse = new MutableLiveData<>();
        }
        return mOrderResponse;
    }

    public LiveData<HistoryResponse> historyResponseLiveData() {
        if (mHistoryResponse == null) {
            mHistoryResponse = new MutableLiveData<>();
        }
        return mHistoryResponse;
    }

    public LiveData<RechargeHistoryResponse> rechargeHistoryResponseLiveData() {
        if (mRechargeHistoryResponse == null) {
            mRechargeHistoryResponse = new MutableLiveData<>();
        }
        return mRechargeHistoryResponse;
    }

    public LiveData<ExpenseSummaryResponse> expenseSummaryResponseLiveData() {
        if (mExpenseSummaryResponse == null) {
            mExpenseSummaryResponse = new MutableLiveData<>();
        }
        return mExpenseSummaryResponse;
    }

    public LiveData<RechargeResponse> rechargeResponseLiveData() {
        if (mRechargeResponse == null) {
            mRechargeResponse = new MutableLiveData<>();
        }
        return mRechargeResponse;
    }

    public LiveData<ExpenseResponse> expenseResponseLiveData() {
        if (mExpenseResponse == null) {
            mExpenseResponse = new MutableLiveData<>();
        }
        return mExpenseResponse;
    }

    public void getCommodities() {
        Log.d(TAG, "getCommodities");
        final Call<CommoditiesResponse> call = mPayApiInterface.getCommodities();
        if (call != null) {
            call.enqueue(new Callback<CommoditiesResponse>() {
                @Override
                public void onResponse(Call<CommoditiesResponse> call,
                                       Response<CommoditiesResponse> response) {
                    Log.d(TAG, "onResponse = " + response);
                    if (mCommoditiesResponse != null) {
                        Log.d(TAG, "body " + response.body());
                        if (200 == response.code()) {
                            mCommoditiesResponse.setValue(response.body());
                        } else {
                            try {
                                String errorString = response.errorBody().string();
                                Log.w(TAG, "error " + errorString);
                                JSONObject jsonObject = new JSONObject(errorString);
                                CommoditiesResponse errorResponse = new CommoditiesResponse();
                                errorResponse.setCode(jsonObject.getInt("code"));
                                errorResponse.setMsg(jsonObject.getString("msg"));
                                mCommoditiesResponse.setValue(errorResponse);
                            } catch (IOException | JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<CommoditiesResponse> call, Throwable t) {
                    Log.w(TAG, t.toString());
                    Toast.makeText(getApplication(), R.string.network_error_default,
                            Toast.LENGTH_SHORT).show();
                    if (mCommoditiesResponse != null) {
                        mCommoditiesResponse.setValue(null);
                    }
                }
            });
        }
    }

    public void getCommodity(String token, String id) {
        Log.d(TAG, "getCommodity");
        final Call<CommodityResponse> call = mPayApiInterface.getCommodity(token, id);
        if (call != null) {
            call.enqueue(new Callback<CommodityResponse>() {
                @Override
                public void onResponse(Call<CommodityResponse> call,
                                       Response<CommodityResponse> response) {
                    Log.d(TAG, "onResponse = " + response);
                    if (mCommodityResponse != null) {
                        Log.d(TAG, "body " + response.body());
                        if (200 == response.code()) {
                            mCommodityResponse.setValue(response.body());
                        } else {
                            try {
                                String errorString = response.errorBody().string();
                                Log.w(TAG, "error " + errorString);
                                JSONObject jsonObject = new JSONObject(errorString);
                                CommodityResponse errorResponse = new CommodityResponse();
                                errorResponse.setCode(jsonObject.getInt("code"));
                                errorResponse.setMsg(jsonObject.getString("msg"));
                                mCommodityResponse.setValue(errorResponse);
                            } catch (IOException | JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<CommodityResponse> call, Throwable t) {
                    Log.w(TAG, t.toString());
                    Toast.makeText(getApplication(), R.string.network_error_default,
                            Toast.LENGTH_SHORT).show();
                    if (mCommodityResponse != null) {
                        mCommodityResponse.setValue(null);
                    }
                }
            });
        }
    }

    public void recharge(String token, RechargeRequest rechargeRequest) {
        Log.d(TAG, "recharge");
        final Call<RechargeResponse> call = mPayApiInterface.recharge(token, rechargeRequest);
        if (call != null) {
            call.enqueue(new Callback<RechargeResponse>() {
                @Override
                public void onResponse(Call<RechargeResponse> call,
                                       Response<RechargeResponse> response) {
                    Log.d(TAG, "onResponse = " + response);
                    if (mRechargeResponse != null) {
                        Log.d(TAG, "body " + response.body());
                        if (200 == response.code()) {
                            mRechargeResponse.setValue(response.body());
                        } else {
                            try {
                                String errorString = response.errorBody().string();
                                Log.w(TAG, "error " + errorString);
                                JSONObject jsonObject = new JSONObject(errorString);
                                RechargeResponse errorResponse = new RechargeResponse();
                                errorResponse.setCode(jsonObject.getInt("code"));
                                errorResponse.setMsg(jsonObject.getString("msg"));
                                mRechargeResponse.setValue(errorResponse);
                            } catch (IOException | JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<RechargeResponse> call, Throwable t) {
                    Log.w(TAG, t.toString());
                    Toast.makeText(getApplication(), R.string.network_error_default,
                            Toast.LENGTH_SHORT).show();
                    if (mRechargeResponse != null) {
                        mRechargeResponse.setValue(null);
                    }
                }
            });
        }
    }

    public void getOrder(String token, String id) {
        Log.d(TAG, "getOrder");
        final Call<DefaultResponse> call = mPayApiInterface.getOrder(token, id);
        if (call != null) {
            call.enqueue(new Callback<DefaultResponse>() {
                @Override
                public void onResponse(Call<DefaultResponse> call,
                                       Response<DefaultResponse> response) {
                    Log.d(TAG, "onResponse = " + response);
                    if (mOrderResponse != null) {
                        Log.d(TAG, "body " + response.body());
                        if (200 == response.code()) {
                            mOrderResponse.setValue(response.body());
                        } else {
                            try {
                                String errorString = response.errorBody().string();
                                Log.w(TAG, "error " + errorString);
                                JSONObject jsonObject = new JSONObject(errorString);
                                DefaultResponse errorResponse = new DefaultResponse();
                                errorResponse.setCode(jsonObject.getInt("code"));
                                errorResponse.setMsg(jsonObject.getString("msg"));
                                mOrderResponse.setValue(errorResponse);
                            } catch (IOException | JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<DefaultResponse> call, Throwable t) {
                    Log.w(TAG, t.toString());
                    Toast.makeText(getApplication(), R.string.network_error_default,
                            Toast.LENGTH_SHORT).show();
                    if (mOrderResponse != null) {
                        mOrderResponse.setValue(null);
                    }
                }
            });
        }
    }

    public void getPayAccount(String token, int id) {
        Log.d(TAG, "getPayAccount id = " + id);
        final Call<AccountResponse> call = mPayApiInterface.getPayAccount(token, id+"");
        if (call != null) {
            call.enqueue(new Callback<AccountResponse>() {
                @Override
                public void onResponse(Call<AccountResponse> call,
                                       Response<AccountResponse> response) {
                    Log.d(TAG, "onResponse = " + response);
                    if (mAccountResponse != null) {
                        Log.d(TAG, "body " + response.body());
                        if (200 == response.code()) {
                            mAccountResponse.setValue(response.body());
                        } else {
                            try {
                                String errorString = response.errorBody().string();
                                Log.w(TAG, "error " + errorString);
                                JSONObject jsonObject = new JSONObject(errorString);
                                AccountResponse errorResponse = new AccountResponse();
                                errorResponse.setCode(jsonObject.getInt("code"));
                                errorResponse.setMsg(jsonObject.getString("msg"));
                                mAccountResponse.setValue(errorResponse);
                            } catch (IOException | JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<AccountResponse> call, Throwable t) {
                    Log.w(TAG, t.toString());
                    Toast.makeText(getApplication(), R.string.network_error_default,
                            Toast.LENGTH_SHORT).show();
                    if (mAccountResponse != null) {
                        mAccountResponse.setValue(null);
                    }
                }
            });
        }
    }

    public void getHistory(String token, int size) {
        Log.d(TAG, "getHistory");
        final Call<HistoryResponse> call = mPayApiInterface.getHistory(token, size);
        if (call != null) {
            call.enqueue(new Callback<HistoryResponse>() {
                @Override
                public void onResponse(Call<HistoryResponse> call,
                                       Response<HistoryResponse> response) {
                    Log.d(TAG, "onResponse = " + response);
                    if (mHistoryResponse != null) {
                        Log.d(TAG, "body " + response.body());
                        if (200 == response.code()) {
                            mHistoryResponse.setValue(response.body());
                        } else {
                            try {
                                String errorString = response.errorBody().string();
                                Log.w(TAG, "error " + errorString);
                                JSONObject jsonObject = new JSONObject(errorString);
                                HistoryResponse errorResponse = new HistoryResponse();
                                errorResponse.setCode(jsonObject.getInt("code"));
                                errorResponse.setMsg(jsonObject.getString("msg"));
                                mHistoryResponse.setValue(errorResponse);
                            } catch (IOException | JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<HistoryResponse> call, Throwable t) {
                    Log.w(TAG, t.toString());
                    Toast.makeText(getApplication(), R.string.network_error_default,
                            Toast.LENGTH_SHORT).show();
                    if (mHistoryResponse != null) {
                        mHistoryResponse.setValue(null);
                    }
                }
            });
        }
    }

    public void getRechargeHistory(String token) {
        Log.d(TAG, "getRechargeHistory");
        final Call<RechargeHistoryResponse> call = mPayApiInterface.getRechargeHistory(token);
        if (call != null) {
            call.enqueue(new Callback<RechargeHistoryResponse>() {
                @Override
                public void onResponse(Call<RechargeHistoryResponse> call,
                                       Response<RechargeHistoryResponse> response) {
                    Log.d(TAG, "onResponse = " + response);
                    if (mRechargeHistoryResponse != null) {
                        Log.d(TAG, "body " + response.body());
                        if (200 == response.code()) {
                            mRechargeHistoryResponse.setValue(response.body());
                        } else {
                            try {
                                String errorString = response.errorBody().string();
                                Log.w(TAG, "error " + errorString);
                                JSONObject jsonObject = new JSONObject(errorString);
                                RechargeHistoryResponse errorResponse = new RechargeHistoryResponse();
                                errorResponse.setCode(jsonObject.getInt("code"));
                                errorResponse.setMsg(jsonObject.getString("msg"));
                                mRechargeHistoryResponse.setValue(errorResponse);
                            } catch (IOException | JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<RechargeHistoryResponse> call, Throwable t) {
                    Log.w(TAG, t.toString());
                    Toast.makeText(getApplication(), R.string.network_error_default,
                            Toast.LENGTH_SHORT).show();
                    if (mRechargeHistoryResponse != null) {
                        mRechargeHistoryResponse.setValue(null);
                    }
                }
            });
        }
    }

    public void getExpenseSummary(String token) {
        Log.d(TAG, "getExpenseSummary");
        final Call<ExpenseSummaryResponse> call = mPayApiInterface.getExpenseSummary(token);
        if (call != null) {
            call.enqueue(new Callback<ExpenseSummaryResponse>() {
                @Override
                public void onResponse(Call<ExpenseSummaryResponse> call,
                                       Response<ExpenseSummaryResponse> response) {
                    Log.d(TAG, "onResponse = " + response);
                    if (mExpenseSummaryResponse != null) {
                        Log.d(TAG, "body " + response.body());
                        if (200 == response.code()) {
                            mExpenseSummaryResponse.setValue(response.body());
                        } else {
                            try {
                                String errorString = response.errorBody().string();
                                Log.w(TAG, "error " + errorString);
                                JSONObject jsonObject = new JSONObject(errorString);
                                ExpenseSummaryResponse errorResponse = new ExpenseSummaryResponse();
                                errorResponse.setCode(jsonObject.getInt("code"));
                                errorResponse.setMsg(jsonObject.getString("msg"));
                                mExpenseSummaryResponse.setValue(errorResponse);
                            } catch (IOException | JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<ExpenseSummaryResponse> call, Throwable t) {
                    Log.w(TAG, t.toString());
                    Toast.makeText(getApplication(), R.string.network_error_default,
                            Toast.LENGTH_SHORT).show();
                    if (mExpenseSummaryResponse != null) {
                        mExpenseSummaryResponse.setValue(null);
                    }
                }
            });
        }
    }

    public void expense(String token, ExpenseRequest expenseRequest) {
        Log.d(TAG, "expense unit = " + expenseRequest.getUnit()
                + "; quantity = " + expenseRequest.getQuantity());
        final Call<ExpenseResponse> call = mPayApiInterface.expense(token, expenseRequest);
        if (call != null) {
            call.enqueue(new Callback<ExpenseResponse>() {
                @Override
                public void onResponse(Call<ExpenseResponse> call,
                                       Response<ExpenseResponse> response) {
                    Log.d(TAG, "onResponse = " + response);
                    if (mExpenseResponse != null) {
                        Log.d(TAG, "body " + response.body());
                        if (200 == response.code()) {
                            mExpenseResponse.setValue(response.body());
                        } else {
                            try {
                                String errorString = response.errorBody().string();
                                Log.w(TAG, "error " + errorString);
                                JSONObject jsonObject = new JSONObject(errorString);
                                ExpenseResponse errorResponse = new ExpenseResponse();
                                errorResponse.setCode(jsonObject.getInt("code"));
                                errorResponse.setMsg(jsonObject.getString("msg"));
                                mExpenseResponse.setValue(errorResponse);
                            } catch (IOException | JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<ExpenseResponse> call, Throwable t) {
                    Log.w(TAG, t.toString());
                    Toast.makeText(getApplication(), R.string.network_error_default,
                            Toast.LENGTH_SHORT).show();
                    if (mExpenseResponse != null) {
                        mExpenseResponse.setValue(null);
                    }
                }
            });
        }
    }
}
